package com.zhudoo.zhilian.util.web;

import com.zhudoo.zhilian.util.DateUtil;
import com.zhudoo.zhilian.util.JsonUtil;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 远程服务调用上下文
 *
 * @author zhudao
 */
public class ServiceContext implements Serializable, Cloneable {

    public static ServiceContext getInstance() {
        return new ServiceContext();
    }

    public ServiceContext() {
    }

    /**
     * 业务顺序，选传
     */
    protected String order;

    /**
     * 分页开始页数
     */
    protected int start = 0;

    /**
     * 前期页
     */
    protected int page = 1;

    /**
     * 分页偏移量，每页条数
     */
    protected int limit = 10;

    /**
     * 全局性业务调用链事务标识,必传
     */
    protected String transactionId;

    /**
     * 参数属性
     */
    protected Map<String, Object> params = new HashMap<>();

    @Override
    public ServiceContext clone() {
        ServiceContext clone = null;
        try {
            clone = (ServiceContext) super.clone();
        } catch (CloneNotSupportedException e) {
            return null;
        }
        return clone;
    }

    @Override
    public String toString() {
        return JsonUtil.object2JSON(this);
    }

    public Integer getParamsInteger(String key) {
        Object obj = this.getParams().get(key);
        if (obj == null) {
            return null;
        }
        if (obj instanceof Integer) {
            return (Integer) obj;
        }
        try {
            return Integer.valueOf((String) obj);
        } catch (Exception ex) {
            return null;
        }
    }

    public Double getParamsDouble(String key) {
        Object obj = this.getParams().get(key);
        if (obj == null) {
            return null;
        }
        if (obj instanceof Double) {
            return (Double) obj;
        }
        return Double.valueOf(obj.toString());
    }

    public Long getParamsLong(String key) {

        Object obj = this.getParams().get(key);
        if (obj == null) {
            return null;
        }
        if (obj instanceof Long) {
            return (Long) obj;
        }
        if (obj instanceof Integer) {
            return Long.valueOf((String.valueOf(obj)));
        }
        return Long.valueOf((String.valueOf(obj)));
    }

    public String getParamsString(String key) {
        Object obj = this.getParams().get(key);
        if (obj == null) {
            return null;
        }
        return obj.toString();
    }

    public Map getParamsMap(String key) {
        Object obj = this.getParams().get(key);
        if (obj == null) {
            return null;
        }
        if (obj instanceof Map) {
            return (Map) obj;
        }
        return (Map) obj;
    }

    public Date getParamsDate(String key) {
        Object obj = this.getParams().get(key);
        if (obj == null) {
            return null;
        }
        if (obj instanceof Date) {
            return (Date) obj;
        }
        if (obj instanceof String) {
            return DateUtil.parseToDate((String) obj);
        }
        return null;
    }

    public BigDecimal getParamsBigDecimal(String key) {
        Object val = this.getParams().get(key);
        if (val == null) {
            return null;
        }
        if (val instanceof BigDecimal) {
            return (BigDecimal) val;
        } else {
            try {
                return new BigDecimal(val.toString()).setScale(2, BigDecimal.ROUND_HALF_DOWN);
            } catch (Exception ex) {
                return null;
            }
        }
    }

    public Boolean getParamsBoolean(String key) {
        Object val = this.getParams().get(key);
        if (val == null) {
            return null;
        }
        return (Boolean) val;
    }

    public Object getParams(String key) {

        return this.getParams().get(key);
    }

    public boolean contains(String key) {

        return this.params.containsKey(key);
    }


    public String getOrder() {
        return order;
    }

    public void setOrder(String order) {
        this.order = order;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getLimit() {
        return limit;
    }

    public void setLimit(int limit) {
        this.limit = limit;
    }

    public String getTransactionId() {
        return transactionId;
    }

    public void setTransactionId(String transactionId) {
        this.transactionId = transactionId;
    }

    public Map<String, Object> getParams() {
        return params;
    }

    public void addParams(String key, Object value) {
        params.put(key, value);
    }

    public void addParams(Map<String, Object> map) {
        params.putAll(map);
    }

}
